package com.avecsys.quotemanager.dao.buyer;

import java.sql.SQLException;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Expression;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.avecsys.quotemanager.dao.common.BaseDAOImpl;
import com.avecsys.quotemanager.dao.common.EnumDBRecordStatus;
import com.avecsys.quotemanager.dao.common.EnumTransactionStatus;
import com.avecsys.quotemanager.exception.DAOException;
import com.avecsys.quotemanager.pojos.BuyerMasterPojo;
import com.avecsys.quotemanager.pojos.BuyerUsersPojo;
import com.avecsys.quotemanager.pojos.SupplierMasterPojo;
import com.avecsys.quotemanager.utils.TransactionStatus;

/**
 * DAO Implementation for buyer master
 * 
 * @author pavkumar
 */
public class BuyerMasterDAOImpl extends BaseDAOImpl implements BuyerMasterDAO
{
	private static final Log log = LogFactory.getLog(BuyerMasterDAOImpl.class);

	@Override
	public TransactionStatus saveBuyer(final BuyerMasterPojo buyerMasterPojo) throws DAOException
	{
		TransactionStatus transactionStatus = new TransactionStatus(
				EnumTransactionStatus.SAVE_SUCESS.ordinal());
		try
		{
			getHibernateTemplate().execute(new HibernateCallback<Object>()
			{
				@Override
				public Object doInHibernate(Session session) throws HibernateException, SQLException
				{
					// 1. Save Company Information
					session.save(buyerMasterPojo.getCompanyMasterPojo());
					// 2. Save Buyer Master Information
					session.save(buyerMasterPojo);
					// 3. Save Default Administrator B User Information
					for (BuyerUsersPojo buyerUsersPojo : buyerMasterPojo.getBuyerUsers())
					{
						session.save(buyerUsersPojo.getUserMasterPojo());
						session.save(buyerUsersPojo);
					}
					return buyerMasterPojo;
				}
			});
		}
		catch (Exception e)
		{
			log.error(e);
			transactionStatus.setStatus(EnumTransactionStatus.SAVE_FAIL.ordinal());
			throw new DAOException(e);
		}
		return transactionStatus;

	}

	@Override
	public TransactionStatus updateBuyer(final BuyerMasterPojo buyerMasterPojo) throws DAOException
	{
		TransactionStatus transactionStatus = new TransactionStatus(
				EnumTransactionStatus.UPDATE_SUCCESS.ordinal());
		try
		{
			getHibernateTemplate().execute(new HibernateCallback<Object>()
			{
				@Override
				public Object doInHibernate(Session session) throws HibernateException, SQLException
				{
					// 1. Save Company Information
					session.update(buyerMasterPojo.getCompanyMasterPojo());
					// 2. Save Buyer Master Information
					session.update(buyerMasterPojo);
					// 3. Save or Update Default Administrator Buyer User
					// Information
					for (BuyerUsersPojo buyerUserPojo : buyerMasterPojo.getBuyerUsers())
					{
						session.saveOrUpdate(buyerUserPojo);
					}
					return buyerMasterPojo;
				}
			});
		}
		catch (Exception e)
		{
			log.error(e);
			transactionStatus.setStatus(EnumTransactionStatus.UPDATE_FAIL.ordinal());
			throw new DAOException(e);
		}
		return transactionStatus;
	}

	@Override
	public TransactionStatus deleteBuyer(final BuyerMasterPojo buyerMasterPojo) throws DAOException
	{
		TransactionStatus transactionStatus = new TransactionStatus(
				EnumTransactionStatus.DELETE_SUCCESS.ordinal());
		try
		{
			getHibernateTemplate().execute(new HibernateCallback<Object>()
			{
				@Override
				public Object doInHibernate(Session session) throws HibernateException, SQLException
				{
					// 1. Mark Buyer as deleted
					buyerMasterPojo.setStatus(EnumDBRecordStatus.DELETED.status());
					session.update(buyerMasterPojo);
					// 3. Save or Update Default Administrator Buyer User
					// Information
					for (BuyerUsersPojo buyerUserPojo : buyerMasterPojo.getBuyerUsers())
					{
						buyerUserPojo.setStatus(EnumDBRecordStatus.DELETED.status());
						session.update(buyerUserPojo);
					}
					return buyerMasterPojo;
				}
			});
		}
		catch (Exception e)
		{
			log.error(e);
			transactionStatus.setStatus(EnumTransactionStatus.DELETE_FAIL.ordinal());
			throw new DAOException(e);
		}
		return transactionStatus;
	}

	/**
	 * Method to return all Active Buyers who belong to a Supplier
	 * 
	 * @param supplierMasterPojo
	 * @return List<BuyerMasterPojo>
	 */
	@Override
	public List<BuyerMasterPojo> findAllSupplierBuyers(final SupplierMasterPojo supplierMasterPojo)
			throws DAOException
	{
		return getHibernateTemplate().execute(new HibernateCallback<List<BuyerMasterPojo>>()
		{
			@Override
			public List<BuyerMasterPojo> doInHibernate(Session session) throws HibernateException,
					SQLException
			{
				final Criteria criteria = session.createCriteria(BuyerMasterPojo.class);
				criteria.add(Expression.eq(
						"supplierMasterPojo.supplierId",
							supplierMasterPojo.getSupplierId()));
				criteria.add(Expression.eq("status", EnumDBRecordStatus.ACTIVE.status()));
				return (List<BuyerMasterPojo>) criteria.list();
			}
		});

	}

}
